home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 21 / AACD 21.iso / AACD / Utilities / Ghostscript / src / gdevdrop.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-01  |  23.0 KB  |  727 lines

  1. /* Copyright (C) 1995, 2000 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of AFPL Ghostscript.
  4.   
  5.   AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author or
  6.   distributor accepts any responsibility for the consequences of using it, or
  7.   for whether it serves any particular purpose or works at all, unless he or
  8.   she says so in writing.  Refer to the Aladdin Free Public License (the
  9.   "License") for full details.
  10.   
  11.   Every copy of AFPL Ghostscript must include a copy of the License, normally
  12.   in a plain ASCII text file named PUBLIC.  The License grants you the right
  13.   to copy, modify and redistribute AFPL Ghostscript, but only under certain
  14.   conditions described in the License.  Among other things, the License
  15.   requires that the copyright notice and this notice be preserved on all
  16.   copies.
  17. */
  18.  
  19. /*$Id: gdevdrop.c,v 1.3 2000/09/19 19:00:12 lpd Exp $ */
  20. /* Default and device-independent RasterOp algorithms */
  21. #include "memory_.h"
  22. #include "gx.h"
  23. #include "gsbittab.h"
  24. #include "gserrors.h"
  25. #include "gsropt.h"
  26. #include "gxcindex.h"
  27. #include "gxdcolor.h"
  28. #include "gxdevice.h"
  29. #include "gxdevmem.h"
  30. #include "gxdevrop.h"
  31. #include "gxgetbit.h"
  32. #include "gdevmem.h"        /* for mem_default_strip_copy_rop prototype */
  33. #include "gdevmrop.h"
  34.  
  35. /*
  36.  * Define the maximum amount of space we are willing to allocate for a
  37.  * multiple-row RasterOp buffer.  (We are always willing to allocate
  38.  * one row, no matter how wide.)
  39.  */
  40. private const uint max_rop_bitmap = 1000;
  41.  
  42. /* ---------------- Debugging aids ---------------- */
  43.  
  44. #ifdef DEBUG
  45.  
  46. void
  47. trace_copy_rop(const char *cname, gx_device * dev,
  48.            const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id,
  49.            const gx_color_index * scolors,
  50.            const gx_strip_bitmap * textures,
  51.            const gx_color_index * tcolors,
  52.            int x, int y, int width, int height,
  53.            int phase_x, int phase_y, gs_logical_operation_t lop)
  54. {
  55.     dlprintf4("%s: dev=0x%lx(%s) depth=%d\n",
  56.           cname, (ulong) dev, dev->dname, dev->color_info.depth);
  57.     dlprintf4("  source data=0x%lx x=%d raster=%u id=%lu colors=",
  58.           (ulong) sdata, sourcex, sraster, (ulong) id);
  59.     if (scolors)
  60.     dprintf2("(%lu,%lu);\n", scolors[0], scolors[1]);
  61.     else
  62.     dputs("none;\n");
  63.     if (textures)
  64.     dlprintf8("  textures=0x%lx size=%dx%d(%dx%d) raster=%u shift=%d(%d)",
  65.           (ulong) textures, textures->size.x, textures->size.y,
  66.           textures->rep_width, textures->rep_height,
  67.           textures->raster, textures->shift, textures->rep_shift);
  68.     else
  69.     dlputs("  textures=none");
  70.     if (tcolors)
  71.     dprintf2(" colors=(%lu,%lu)\n", tcolors[0], tcolors[1]);
  72.     else
  73.     dputs(" colors=none\n");
  74.     dlprintf7("  rect=(%d,%d),(%d,%d) phase=(%d,%d) op=0x%x\n",
  75.           x, y, x + width, y + height, phase_x, phase_y,
  76.           (uint) lop);
  77.     if (gs_debug_c('B')) {
  78.     if (sdata)
  79.         debug_dump_bitmap(sdata, sraster, height, "source bits");
  80.     if (textures && textures->data)
  81.         debug_dump_bitmap(textures->data, textures->raster,
  82.                   textures->size.y, "textures bits");
  83.     }
  84. }
  85.  
  86. #endif
  87.  
  88. /* ---------------- Default copy_rop implementations ---------------- */
  89.  
  90. /*
  91.  * The default implementation for non-memory devices uses get_bits_rectangle
  92.  * to read out the pixels, the memory device implementation to do the
  93.  * operation, and copy_color to write the pixels back.
  94.  */
  95. int
  96. gx_default_strip_copy_rop(gx_device * dev,
  97.               const byte * sdata, int sourcex,
  98.               uint sraster, gx_bitmap_id id,
  99.               const gx_color_index * scolors,
  100.               const gx_strip_bitmap * textures,
  101.               const gx_color_index * tcolors,
  102.               int x, int y, int width, int height,
  103.               int phase_x, int phase_y,
  104.               gs_logical_operation_t lop)
  105. {
  106.     int depth = dev->color_info.depth;
  107.     gs_memory_t *mem = dev->memory;
  108.     const gx_device_memory *mdproto = gdev_mem_device_for_bits(depth);
  109.     gx_device_memory mdev;
  110.     uint draster;
  111.     byte *row = 0;
  112.     gs_int_rect rect;
  113.     int max_height;
  114.     int block_height;
  115.     int code;
  116.     int py;
  117.  
  118. #ifdef DEBUG
  119.     if (gs_debug_c('b'))
  120.     trace_copy_rop("gx_default_strip_copy_rop",
  121.                dev, sdata, sourcex, sraster,
  122.                id, scolors, textures, tcolors,
  123.                x, y, width, height, phase_x, phase_y, lop);
  124. #endif
  125.     if (mdproto == 0)
  126.     return_error(gs_error_rangecheck);
  127.     if (sdata == 0) {
  128.     fit_fill(dev, x, y, width, height);
  129.     } else {
  130.     fit_copy(dev, sdata, sourcex, sraster, id, x, y, width, height);
  131.     }
  132.     draster = bitmap_raster(width * depth);
  133.     max_height = max_rop_bitmap / draster;
  134.     if (max_height == 0)
  135.     max_height = 1;
  136.     block_height = min(height, max_height);
  137.     gs_make_mem_device(&mdev, mdproto, mem, -1, dev);
  138.     gx_device_retain((gx_device *)&mdev, true);    /* prevent freeing */
  139.     mdev.width = width;
  140.     mdev.height = block_height;
  141.     mdev.bitmap_memory = mem;
  142.     mdev.color_info = dev->color_info;
  143.     code = (*dev_proc(&mdev, open_device))((gx_device *)&mdev);
  144.     if (code < 0)
  145.     return code;
  146.     if (rop3_uses_D(gs_transparent_rop(lop))) {
  147.     row = gs_alloc_bytes(mem, draster * block_height, "copy_rop row");
  148.     if (row == 0) {
  149.         code = gs_note_error(gs_error_VMerror);
  150.         goto out;
  151.     }
  152.     }
  153.     rect.p.x = x;
  154.     rect.q.x = x + width;
  155.     for (py = y; py < y + height; py += block_height) {
  156.     if (block_height > y + height - py)
  157.         block_height = y + height - py;
  158.     rect.p.y = py;
  159.     rect.q.y = py + block_height;
  160.     if (row /*uses_d*/) {
  161.         gs_get_bits_params_t bit_params;
  162.  
  163.         bit_params.options =
  164.         GB_COLORS_NATIVE | GB_ALPHA_NONE | GB_DEPTH_ALL |
  165.         GB_PACKING_CHUNKY | GB_RETURN_ALL | GB_ALIGN_STANDARD |
  166.         GB_OFFSET_0 | GB_OFFSET_ANY | GB_RASTER_STANDARD;
  167.         bit_params.data[0] = row;
  168.         bit_params.x_offset = 0;
  169.         code = (*dev_proc(dev, get_bits_rectangle))
  170.         (dev, &rect, &bit_params, NULL);
  171.         if (code < 0)
  172.         break;
  173.         code = (*dev_proc(&mdev, copy_color))
  174.         ((gx_device *)&mdev, bit_params.data[0], bit_params.x_offset,
  175.          draster, gx_no_bitmap_id, 0, 0, width,
  176.          block_height);
  177.         if (code < 0)
  178.         return code;
  179.     }
  180.     code = (*dev_proc(&mdev, strip_copy_rop))
  181.         ((gx_device *)&mdev,
  182.          sdata + (py - y) * sraster, sourcex, sraster,
  183.          gx_no_bitmap_id, scolors, textures, tcolors,
  184.          0, 0, width, block_height, phase_x + x, phase_y + py, lop);
  185.     if (code < 0)
  186.         break;
  187.     code = (*dev_proc(dev, copy_color))
  188.         (dev, scan_line_base(&mdev, 0), 0, draster, gx_no_bitmap_id,
  189.          x, py, width, block_height);
  190.     if (code < 0)
  191.         break;
  192.     }
  193. out:
  194.     gs_free_object(mem, row, "copy_rop row");
  195.     (*dev_proc(&mdev, close_device))((gx_device *)&mdev);
  196.     return code;
  197. }
  198.  
  199. /* ---------------- Default memory device copy_rop ---------------- */
  200.  
  201. /* Convert color constants to standard RGB representation. */
  202. private void
  203. unpack_colors_to_standard(gx_device * dev, gx_color_index real_colors[2],
  204.               const gx_color_index * colors, int depth)
  205. {
  206.     int i;
  207.  
  208.     for (i = 0; i < 2; ++i) {
  209.     gx_color_value rgb[3];
  210.     gx_color_index pixel;
  211.  
  212.     (*dev_proc(dev, map_color_rgb)) (dev, colors[i], rgb);
  213.     pixel = gx_color_value_to_byte(rgb[0]);
  214.     if (depth > 8) {
  215.         pixel = (pixel << 16) +
  216.         (gx_color_value_to_byte(rgb[1]) << 8) +
  217.         gx_color_value_to_byte(rgb[2]);
  218.     }
  219.     real_colors[i] = pixel;
  220.     }
  221. }
  222.  
  223. /*
  224.  * Convert RGB to the device's native format.  We special-case this for
  225.  * 1-bit CMYK devices.
  226.  */
  227. private void
  228. pack_cmyk_1bit_from_standard(gx_device * dev, byte * dest, int destx,
  229.                  const byte * src, int width, int depth,
  230.                  int src_depth)
  231. {
  232.     /*
  233.      * This routine is only called if dev_proc(dev, map_cmyk_color) ==
  234.      * cmyk_1bit_map_cmyk_color (implying depth == 4) and src_depth == 24.
  235.      */
  236.     int bit_x = destx * 4;
  237.     byte *dp = dest + (bit_x >> 3);
  238.     bool hi = (bit_x & 4) != 0;     /* true if last nibble filled was hi */
  239.     byte buf = (hi ? *dp & 0xf0 : 0);
  240.     const byte *sp = src;
  241.     int x;
  242.  
  243.     for (x = width; --x >= 0; sp += 3) {
  244.     byte r = sp[0], g = sp[1], b = sp[2];
  245.     byte pixel =
  246.         (r | g | b ?
  247.          (((r >> 4) & 8) | ((g >> 5) & 4) | ((b >> 6) & 2)) ^ 0xe : 1);
  248.  
  249.     if ((hi = !hi))
  250.         buf = pixel << 4;
  251.     else
  252.         *dp++ = buf | pixel;
  253.     }
  254.     if (hi && width > 0)
  255.     *dp = buf | (*dp & 0xf);
  256.  
  257. }
  258.  
  259. private gx_color_index
  260. map_rgb_to_color_via_cmyk(gx_device * dev, gx_color_value r,
  261.               gx_color_value g, gx_color_value b)
  262. {
  263.     gx_color_value c = gx_max_color_value - r;
  264.     gx_color_value m = gx_max_color_value - g;
  265.     gx_color_value y = gx_max_color_value - b;
  266.     gx_color_value k = (c < m ? min(c, y) : min(m, y));
  267.  
  268.     return (*dev_proc(dev, map_cmyk_color)) (dev, c - k, m - k, y - k, k);
  269. }
  270. private void
  271. pack_from_standard(gx_device * dev, byte * dest, int destx, const byte * src,
  272.            int width, int depth, int src_depth)
  273. {
  274.     dev_proc_map_rgb_color((*map)) =
  275.     (dev->color_info.num_components == 4 ?
  276.      map_rgb_to_color_via_cmyk : dev_proc(dev, map_rgb_color));
  277.     int bit_x = destx * depth;
  278.     byte *dp = dest + (bit_x >> 3);
  279.     int shift = (~bit_x & 7) + 1;
  280.     byte buf = (shift == 8 ? 0 : *dp & (0xff00 >> shift));
  281.     const byte *sp = src;
  282.     int x;
  283.  
  284.     for (x = width; --x >= 0;) {
  285.     byte vr, vg, vb;
  286.     gx_color_value r, g, b;
  287.     gx_color_index pixel;
  288.     byte chop = 0x1;
  289.  
  290.     vr = *sp++;
  291.     if (src_depth > 8) {
  292.         vg = *sp++;
  293.         vb = *sp++;
  294.     } else
  295.         vb = vg = vr;
  296.     /*
  297.      * We have to map back to some pixel value, even if the color
  298.      * isn't accurate.
  299.      */
  300.     for (;;) {
  301.         r = gx_color_value_from_byte(vr);
  302.         g = gx_color_value_from_byte(vg);
  303.         b = gx_color_value_from_byte(vb);
  304.         pixel = (*map) (dev, r, g, b);
  305.         if (pixel != gx_no_color_index)
  306.         break;
  307.         /* Reduce the color accuracy and try again. */
  308.         vr = (vr >= 0x80 ? vr | chop : vr & ~chop);
  309.         vg = (vg >= 0x80 ? vg | chop : vg & ~chop);
  310.         vb = (vb >= 0x80 ? vb | chop : vb & ~chop);
  311.         chop <<= 1;
  312.     }
  313.     if ((shift -= depth) >= 0)
  314.         buf += (byte)(pixel << shift);
  315.     else {
  316.         switch (depth) {
  317.         default:        /* 1, 2, 4, 8 */
  318.         *dp++ = buf;
  319.         shift += 8;
  320.         buf = (byte)(pixel << shift);
  321.         break;
  322.         case 32:
  323.         *dp++ = (byte)(pixel >> 24);
  324.         *dp++ = (byte)(pixel >> 16);
  325.         case 16:
  326.         *dp++ = (byte)(pixel >> 8);
  327.         *dp++ = (byte)pixel;
  328.         shift = 0;
  329.         }
  330.     }
  331.     }
  332.     if (width > 0 && depth <= 8)
  333.     *dp = (shift == 0 ? buf : buf + (*dp & ((1 << shift) - 1)));
  334. }
  335.  
  336. /*
  337.  * The default implementation for memory devices uses get_bits_rectangle to
  338.  * read out the pixels and convert them to standard (8-bit gray or 24-bit
  339.  * RGB) representation, the standard memory device implementation to do the
  340.  * operation, pack_from_standard to convert them back to the device
  341.  * representation, and copy_color to write the pixels back.
  342.  */
  343. int
  344. mem_default_strip_copy_rop(gx_device * dev,
  345.               const byte * sdata, int sourcex,
  346.               uint sraster, gx_bitmap_id id,
  347.               const gx_color_index * scolors,
  348.               const gx_strip_bitmap * textures,
  349.               const gx_color_index * tcolors,
  350.               int x, int y, int width, int height,
  351.               int phase_x, int phase_y,
  352.               gs_logical_operation_t lop)
  353. {
  354.     int depth = dev->color_info.depth;
  355.     int rop_depth = (gx_device_has_color(dev) ? 24 : 8);
  356.     void (*pack)(P7(gx_device *, byte *, int, const byte *, int, int, int)) =
  357.     (dev_proc(dev, map_cmyk_color) == cmyk_1bit_map_cmyk_color &&
  358.      rop_depth == 24 ? pack_cmyk_1bit_from_standard : pack_from_standard);
  359.     const gx_bitmap_format_t no_expand_options =
  360.     GB_COLORS_NATIVE | GB_ALPHA_NONE | GB_DEPTH_ALL |
  361.     GB_PACKING_CHUNKY | GB_RETURN_ALL | GB_ALIGN_STANDARD |
  362.     GB_OFFSET_0 | GB_OFFSET_ANY | GB_RASTER_STANDARD;
  363.     const gx_bitmap_format_t expand_options =
  364.     (rop_depth > 8 ? GB_COLORS_RGB : GB_COLORS_GRAY) |
  365.     GB_ALPHA_NONE | GB_DEPTH_8 |
  366.     GB_PACKING_CHUNKY | GB_RETURN_COPY | GB_ALIGN_STANDARD |
  367.     GB_OFFSET_0 | GB_RASTER_STANDARD;
  368.     gs_memory_t *mem = dev->memory;
  369.     const gx_device_memory *mdproto = gdev_mem_device_for_bits(rop_depth);
  370.     gx_device_memory mdev;
  371.     union { long l; void *p; } mdev_storage[20];
  372.     uint row_raster = bitmap_raster(width * depth);
  373.     gs_rop3_t trans_rop = gs_transparent_rop(lop);
  374.     bool uses_d = rop3_uses_D(trans_rop);
  375.     bool uses_s = rop3_uses_S(trans_rop);
  376.     bool uses_t = rop3_uses_T(trans_rop);
  377.     bool expand_s, expand_t;
  378.     byte *row = 0;
  379.     union { long l; void *p; } dest_buffer[16];
  380.     byte *source_row = 0;
  381.     uint source_row_raster;
  382.     union { long l; void *p; } source_buffer[16];
  383.     byte *texture_row = 0;
  384.     uint texture_row_raster;
  385.     union { long l; void *p; } texture_buffer[16];
  386.     gx_color_index source_colors[2];
  387.     const gx_color_index *real_scolors = scolors;
  388.     gx_color_index texture_colors[2];
  389.     const gx_color_index *real_tcolors = tcolors;
  390.     gx_strip_bitmap rop_texture;
  391.     const gx_strip_bitmap *real_texture = textures;
  392.     gs_int_rect rect;
  393.     gs_get_bits_params_t bit_params;
  394.     gs_get_bits_params_t expand_params;
  395.     gs_get_bits_params_t no_expand_params;
  396.     int max_height;
  397.     int block_height, loop_height;
  398.     int code;
  399.     int py;
  400.  
  401. /*
  402.  * Allocate a temporary row buffer.  Free variables: mem, block_height.
  403.  * Labels used: out.
  404.  */
  405. #define ALLOC_BUF(buf, prebuf, size, cname)\
  406.     BEGIN\
  407.       uint num_bytes = (size) * block_height;\
  408. \
  409.       if (num_bytes <= sizeof(prebuf))\
  410.         buf = (byte *)prebuf;\
  411.       else {\
  412.         buf = gs_alloc_bytes(mem, num_bytes, cname);\
  413.         if (buf == 0) {\
  414.           code = gs_note_error(gs_error_VMerror);\
  415.           goto out;\
  416.         }\
  417.       }\
  418.     END
  419.  
  420. #ifdef DEBUG
  421.     if (gs_debug_c('b'))
  422.     trace_copy_rop("mem_default_strip_copy_rop",
  423.                dev, sdata, sourcex, sraster,
  424.                id, scolors, textures, tcolors,
  425.                x, y, width, height, phase_x, phase_y, lop);
  426. #endif
  427.     if (mdproto == 0)
  428.     return_error(gs_error_rangecheck);
  429.     if (sdata == 0) {
  430.     fit_fill(dev, x, y, width, height);
  431.     } else {
  432.     fit_copy(dev, sdata, sourcex, sraster, id, x, y, width, height);
  433.     }
  434.     /* Compute max_height conservatively. */
  435.     max_height = max_rop_bitmap / (width * rop_depth);
  436.     if (max_height == 0)
  437.     max_height = 1;
  438.     block_height = min(height, max_height);
  439.     expand_s = scolors == 0 && uses_s;
  440.     expand_t = tcolors == 0 && uses_t;
  441.     no_expand_params.options = no_expand_options;
  442.     if (expand_t) {
  443.     /*
  444.      * We don't want to wrap around more than once in Y when
  445.      * copying the texture to the intermediate buffer.
  446.      */
  447.     if (textures->size.y < block_height)
  448.         block_height = textures->size.y;
  449.     }
  450.     gs_make_mem_device(&mdev, mdproto, mem, -1, NULL);
  451.     gx_device_retain((gx_device *)&mdev, true);    /* prevent freeing */
  452.     mdev.width = width;
  453.     mdev.height = block_height;
  454.     mdev.color_info.num_components = rop_depth >> 3;
  455.     if (gdev_mem_data_size(&mdev, width, block_height) <= sizeof(mdev_storage)) {
  456.     /* Use the locally allocated storage. */
  457.     mdev.base = (byte *)mdev_storage;
  458.     mdev.line_ptrs = (byte **)
  459.         (mdev.base + gdev_mem_bits_size(&mdev, mdev.width, mdev.height));
  460.     } else {
  461.     mdev.bitmap_memory = mem;
  462.     }
  463.     code = (*dev_proc(&mdev, open_device))((gx_device *)&mdev);
  464.     if (code < 0)
  465.     return code;
  466.     ALLOC_BUF(row, dest_buffer, row_raster, "copy_rop row");
  467.     /* We may need intermediate buffers for all 3 operands. */
  468.     if (expand_s) {
  469.     source_row_raster = bitmap_raster(width * rop_depth);
  470.     ALLOC_BUF(source_row, source_buffer, source_row_raster,
  471.           "copy_rop source_row");
  472.     }
  473.     if (scolors && uses_s) {
  474.     unpack_colors_to_standard(dev, source_colors, scolors, rop_depth);
  475.     real_scolors = source_colors;
  476.     }
  477.     if (expand_t) {
  478.     texture_row_raster = bitmap_raster(textures->rep_width * rop_depth);
  479.     ALLOC_BUF(texture_row, texture_buffer, texture_row_raster,
  480.           "copy_rop texture_row");
  481.     rop_texture = *textures;
  482.     rop_texture.data = texture_row;
  483.     rop_texture.raster = texture_row_raster;
  484.     rop_texture.size.x = rop_texture.rep_width;
  485.     rop_texture.id = gs_no_bitmap_id;
  486.     real_texture = &rop_texture;
  487.     }
  488.     if (tcolors && uses_t) {
  489.     unpack_colors_to_standard(dev, texture_colors, tcolors, rop_depth);
  490.     real_tcolors = texture_colors;
  491.     }
  492.     expand_params.options = expand_options;
  493.     expand_params.x_offset = 0;
  494.     rect.p.x = x;
  495.     rect.q.x = x + width;
  496.     for (py = y; py < y + height; py += loop_height) {
  497.     int sx = sourcex;
  498.     const byte *source_data = sdata + (py - y) * sraster;
  499.     uint source_raster = sraster;
  500.  
  501.     if (block_height > y + height - py)
  502.         block_height = y + height - py;
  503.     rect.p.y = py;
  504.     if (expand_t) {
  505.         int rep_y = (phase_y + py) % rop_texture.rep_height;
  506.  
  507.         loop_height = min(block_height, rop_texture.size.y - rep_y);
  508.         rect.q.y = py + loop_height;
  509.         expand_params.data[0] = texture_row;
  510.         gx_get_bits_copy(dev, 0, textures->rep_width, loop_height,
  511.                  &expand_params, &no_expand_params,
  512.                  textures->data + rep_y * textures->raster,
  513.                  textures->raster);
  514.         /*
  515.          * Compensate for the addition of rep_y * raster
  516.          * in the subsidiary strip_copy_rop call.
  517.          */
  518.         rop_texture.data = texture_row - rep_y * rop_texture.raster;
  519.     } else {
  520.         loop_height = block_height;
  521.         rect.q.y = py + block_height;
  522.     }
  523.     if (uses_d) {
  524.         bit_params.options = expand_options;
  525.         bit_params.data[0] = scan_line_base(&mdev, 0);
  526.         bit_params.x_offset = 0;
  527.         code = (*dev_proc(dev, get_bits_rectangle))
  528.         (dev, &rect, &bit_params, NULL);
  529.         if (code < 0)
  530.         break;
  531.     }
  532.     /* Convert the source and texture to standard format. */
  533.     if (expand_s) {
  534.         expand_params.data[0] = source_row;
  535.         gx_get_bits_copy(dev, sx, width, loop_height, &expand_params,
  536.                  &no_expand_params, source_data, sraster);
  537.         sx = 0;
  538.         source_data = source_row;
  539.         source_raster = source_row_raster;
  540.     }
  541.     code = (*dev_proc(&mdev, strip_copy_rop))
  542.         ((gx_device *)&mdev, source_data, sx, source_raster,
  543.          gx_no_bitmap_id, real_scolors, real_texture, real_tcolors,
  544.          0, 0, width, loop_height, phase_x + x, phase_y + py, lop);
  545.     if (code < 0)
  546.         break;
  547.     {
  548.         /*
  549.          * Convert the result back to the device's format.  We know
  550.          * the device is a memory device, so we can store the result
  551.          * directly into its scan lines.
  552.          */
  553.         int i;
  554.         const byte *unpacked = scan_line_base(&mdev, 0);
  555.  
  556.         for (i = 0; i < loop_height; unpacked += mdev.raster, ++i) {
  557.         byte *packed = scan_line_base((gx_device_memory *)dev, py + i);
  558.  
  559.         pack(dev, packed, x, unpacked, width, depth, rop_depth);
  560.         }
  561.     }
  562.     }
  563. out:
  564.     if (texture_row != 0 && texture_row != (byte *)texture_buffer)
  565.     gs_free_object(mem, texture_row, "copy_rop texture_row");
  566.     if (source_row != 0 && source_row != (byte *)source_buffer)
  567.     gs_free_object(mem, source_row, "copy_rop source_row");
  568.     if (row != 0 && row != (byte *)dest_buffer)
  569.     gs_free_object(mem, row, "copy_rop row");
  570.     (*dev_proc(&mdev, close_device)) ((gx_device *) & mdev);
  571.     return code;
  572. }
  573.  
  574. /* ------ Implementation of related functions ------ */
  575.  
  576. int
  577. gx_default_copy_rop(gx_device * dev,
  578.          const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id,
  579.             const gx_color_index * scolors,
  580.          const gx_tile_bitmap * texture, const gx_color_index * tcolors,
  581.             int x, int y, int width, int height,
  582.             int phase_x, int phase_y, gs_logical_operation_t lop)
  583. {
  584.     const gx_strip_bitmap *textures;
  585.     gx_strip_bitmap tiles;
  586.  
  587.     if (texture == 0)
  588.     textures = 0;
  589.     else {
  590.     *(gx_tile_bitmap *) & tiles = *texture;
  591.     tiles.rep_shift = tiles.shift = 0;
  592.     textures = &tiles;
  593.     }
  594.     return (*dev_proc(dev, strip_copy_rop))
  595.     (dev, sdata, sourcex, sraster, id, scolors, textures, tcolors,
  596.      x, y, width, height, phase_x, phase_y, lop);
  597. }
  598.  
  599. int
  600. gx_copy_rop_unaligned(gx_device * dev,
  601.          const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id,
  602.               const gx_color_index * scolors,
  603.          const gx_tile_bitmap * texture, const gx_color_index * tcolors,
  604.               int x, int y, int width, int height,
  605.               int phase_x, int phase_y, gs_logical_operation_t lop)
  606. {
  607.     const gx_strip_bitmap *textures;
  608.     gx_strip_bitmap tiles;
  609.  
  610.     if (texture == 0)
  611.     textures = 0;
  612.     else {
  613.     *(gx_tile_bitmap *) & tiles = *texture;
  614.     tiles.rep_shift = tiles.shift = 0;
  615.     textures = &tiles;
  616.     }
  617.     return gx_strip_copy_rop_unaligned
  618.     (dev, sdata, sourcex, sraster, id, scolors, textures, tcolors,
  619.      x, y, width, height, phase_x, phase_y, lop);
  620. }
  621.  
  622. int
  623. gx_strip_copy_rop_unaligned(gx_device * dev,
  624.          const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id,
  625.                 const gx_color_index * scolors,
  626.        const gx_strip_bitmap * textures, const gx_color_index * tcolors,
  627.                 int x, int y, int width, int height,
  628.                int phase_x, int phase_y, gs_logical_operation_t lop)
  629. {
  630.     dev_proc_strip_copy_rop((*copy_rop)) = dev_proc(dev, strip_copy_rop);
  631.     int depth = (scolors == 0 ? dev->color_info.depth : 1);
  632.     int step = sraster & (align_bitmap_mod - 1);
  633.  
  634.     /* Adjust the origin. */
  635.     if (sdata != 0) {
  636.     uint offset =
  637.     (uint) (sdata - (const byte *)0) & (align_bitmap_mod - 1);
  638.  
  639.     /* See copy_color above re the following statement. */
  640.     if (depth == 24)
  641.         offset += (offset % 3) *
  642.         (align_bitmap_mod * (3 - (align_bitmap_mod % 3)));
  643.     sdata -= offset;
  644.     sourcex += (offset << 3) / depth;
  645.     }
  646.     /* Adjust the raster. */
  647.     if (!step || sdata == 0 ||
  648.     (scolors != 0 && scolors[0] == scolors[1])
  649.     ) {            /* No adjustment needed. */
  650.     return (*copy_rop) (dev, sdata, sourcex, sraster, id, scolors,
  651.                 textures, tcolors, x, y, width, height,
  652.                 phase_x, phase_y, lop);
  653.     }
  654.     /* Do the transfer one scan line at a time. */
  655.     {
  656.     const byte *p = sdata;
  657.     int d = sourcex;
  658.     int dstep = (step << 3) / depth;
  659.     int code = 0;
  660.     int i;
  661.  
  662.     for (i = 0; i < height && code >= 0;
  663.          ++i, p += sraster - step, d += dstep
  664.         )
  665.         code = (*copy_rop) (dev, p, d, sraster, gx_no_bitmap_id, scolors,
  666.                 textures, tcolors, x, y + i, width, 1,
  667.                 phase_x, phase_y, lop);
  668.     return code;
  669.     }
  670. }
  671.  
  672. /* ---------------- Internal routines ---------------- */
  673.  
  674. /* Compute the effective RasterOp for the 1-bit case, */
  675. /* taking transparency into account. */
  676. gs_rop3_t
  677. gs_transparent_rop(gs_logical_operation_t lop)
  678. {
  679.     gs_rop3_t rop = lop_rop(lop);
  680.  
  681.     /*
  682.      * The algorithm for computing an effective RasterOp is presented,
  683.      * albeit obfuscated, in the H-P PCL5 technical documentation.
  684.      * Define So ("source opaque") and Po ("pattern opaque") as masks
  685.      * that have 1-bits precisely where the source or pattern
  686.      * respectively are not white (transparent).
  687.      * One applies the original RasterOp to compute an intermediate
  688.      * result R, and then computes the final result as
  689.      * (R & M) | (D & ~M) where M depends on transparencies as follows:
  690.      *      s_tr    p_tr    M
  691.      *       0       0      1
  692.      *       0       1      ~So | Po (? Po ?)
  693.      *       1       0      So
  694.      *       1       1      So & Po
  695.      * The s_tr = 0, p_tr = 1 case seems wrong, but it's clearly
  696.      * specified that way in the "PCL 5 Color Technical Reference
  697.      * Manual."
  698.      *
  699.      * In the 1-bit case, So = ~S and Po = ~P, so we can apply the
  700.      * above table directly.
  701.      */
  702. #define So rop3_not(rop3_S)
  703. #define Po rop3_not(rop3_T)
  704. #ifdef TRANSPARENCY_PER_H_P
  705. /*
  706.  * Believe it or not, MPo depends on S in this case even if the original
  707.  * RasterOp didn't depend on S.
  708.  */
  709. #  define MPo (rop3_not(So) | Po)
  710. #else
  711. #  define MPo Po
  712. #endif
  713.     /*
  714.      * If the operation doesn't use S or T, we must disregard the
  715.      * corresponding transparency flag.
  716.      */
  717. #define source_transparent ((lop & lop_S_transparent) && rop3_uses_S(rop))
  718. #define pattern_transparent ((lop & lop_T_transparent) && rop3_uses_T(rop))
  719.     gs_rop3_t mask =
  720.     (source_transparent ?
  721.      (pattern_transparent ? So & Po : So) :
  722.      (pattern_transparent ? MPo : rop3_1));
  723.  
  724. #undef MPo
  725.     return (rop & mask) | (rop3_D & ~mask);
  726. }
  727.